// 1.求任意数的和
function sum(){
    var s=0;
    for(i=0;i<arguments.length;i++){
        s+=arguments[i];
    }
    return s;
}
// 2.求最大数
function max(){
    var big=arguments[0];
    for(i=0;i<=arguments.length;i++){
        if(arguments[i]>big){
            big=arguments[i];
        }
    }
    return big;
}
// 3.求最小数
function min(){
    var small=arguments[0];
    for(i=0;i<=arguments.length;i++){
        if(arguments[i]<small){
            small=arguments[i];
        }
    }
    return small;
}
// 4.递归求n！
  function jieceng(n) {

            if (n == 1) {
                return 1;
            }
            var str = n * jieceng(--n);
            return str;
        }

//5.生成随机整数
     function random(n, m) {
            // var n = 20;
            // var m = 50;
            var max = m > n ? m : n;
            var min = m < n ? m : n;
            var res;
            res = parseInt(Math.random() * (max - min + 1) + min)
            return res;
        }
//6.生成随机颜色
 function color(r, g, b) {
            r = parseInt(Math.random() * 255);
            g = parseInt(Math.random() * 255);
            b = parseInt(Math.random() * 255);
            var res = "rgb(" + r + "," + g + "," + b + ")";
            return res;
        }
//7. 数组去重
  function norepeat(arr) {
            // 先遍历数组
            for (i = 0; i < arr.length; i++) {
                // 判断数组中的每一个数与其他数是否相等，相等则去除其他的数
                // 创建内层循环，遍历数组，并与外层循环的数比较
                for (j = i; j < arr.length; j++) {
                    if (arr[i] == arr[j] && i != j) {
                        arr.splice(j, 1);
                        j--;
                    }
                }

            }
            // console.log(arr)
            return arr;
        }
//8. 统计字符串中每个字符个数
  function strredunce(str) {
            var obj = {};
            // 使用for循环遍历字符串
            for (i = 0; i < str.length; i++) {
                // 对对象进行判断，如果对象中存在循环得到的字符串字符，则值+1；如果不存在则给该属性赋值1；
                if (obj[str[i]]) {
                    obj[str[i]] += 1;
                } else {
                    obj[str[i]] = 1;
                }
                // console.log(str[i]);
            }
            return obj;
        }
// 9.时间格式化显示
 function geshihuaDate(date) {
            // 获取时间对象中的数据
            // 获取年份
            var year = date.getFullYear();
            // 获取月份
            var month = date.getMonth() + 1;
            month = month >=10 ? month : "0" + month;
            // 获取日期
            var dates = date.getDate();
            dates = dates >= 10 ? dates : "0" + dates;
            // 获取时，分，秒，星期
            var hour = date.getHours();
            hour = hour >= 10 ? hour : "0" + hour;
            var min = date.getMinutes();
            min = min >=10 ? min : "0" + min;
            var second = date.getSeconds();
            second = second >=10 ? second : "0" + second;
            var day = date.getDay();
            // 定义数组规范星期的表达
            var arr = ["星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
            return {
                y: year,
                m: month,
                da: dates,
                h: hour,
                min: min,
                s: second,
                day: arr[day]

            }

        }
// 10.求两个时间的时间差函数
function timeDifference(date1, date2) {
            // 获得两个时间对象的时间戳
            var time1 = date1.getTime();
            var time2 = date2.getTime();
            // 获得两个时间戳的差值
            var dif = Math.abs(time1 - time2);
            // 将差值转换为以天，时，分，秒表示
            var day = parseInt(dif / 1000 / 60 / 60 / 24);
            day = day >= 10 ? day : "0" + day;
            var hours = parseInt(dif / 1000 / 60 / 60) % 24;
            hours = hours >= 10 ? hours : "0" + hours;
            var minutes = parseInt(dif / 1000 / 60) % 60;
            minutes = minutes >= 10 ? minutes : "0" + minutes;
            var seconds = parseInt(dif / 1000) % 60;
            seconds = seconds >= 10 ? seconds : "0" + seconds;
            return {
                day:day,
                hours:hours,
                minutes:minutes,
                seconds:seconds
            }
        }
// 11.封装一个获取样式的函数
//    参数：
//         ele:获取样式的元素
//         attr:获取什么样式
//     返回值：
//         获取的样式
function getStyle(ele,attr){
    var style;
    if (window.getComputedStyle) {
        style = window.getComputedStyle(ele)[attr];
    } else {
        style = ele.currentStyle[attr];
    }

    return style;
}
// 12.封装一个给函数设置样式的函数
//  参数：
//                     给哪个元素设置样式
//                     设置什么属性的样式
//                     属性的属性值是什么？
//                     如果同时设置多个样式的时候？
//                 返回值：不需要返回值
// 由于可能需要设置多个属性以及样式，可以将属性：属性值放入一个对象中
function setstyle(ele,obj){
    for(var key in obj){
        ele.style[key]=obj[key];
    }
}
// 13.封装缓冲运动的函数
        // ele dom元素，必须
        // attr 需要操作的属性
        // target 目标值
        // time 定时器的时间
        function huanchong(ele, attr, target, time) {
            let styles = parseInt(getstyle(ele, attr));
            ele.timer = setInterval(() => {



                let speed = (target - styles) / 10;

                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);

                styles += speed;
                console.log(styles);
                ele.style[attr] = styles + "px";

                if (styles == target) {
                    clearInterval(ele.timer)
                }
            }, time)
        }

// 14.封装改变多属性的动画函数
/* 
    参数：
        ele：dom          参与动画的元素（必须）
        option:object     参与动画的属性 和目标是 （必须）
        callback:function 动画执行完成之后需要执行代码（选填）
*/
function move(ele, option, callback,time) {
    let len = 0; // 用于记录动画的个数（参与动画的属性个数）
    for (let key in option) {
        len++;
        clearInterval(ele[key]);
        ele[key] = setInterval(() => {
            let style = parseInt(getStyle(ele, key));

            let speed = (option[key] - style) / 10;
            speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
            style += speed;

            ele.style[key] = style + "px";
            if (style == option[key]) {
                clearInterval(ele[key]);
                len--;
                if (len != 0) return;
                callback && callback();
            }
        },time);
    }
}
// 15.封装一个ajax函数
    //  参数：
    //                 请求的路径
    //                 请求方式
    //                 是否异步
    //                 请求的参数
    //                 请求成功的回调函数
    //                 请求失败的回调函数

    //                 因为这些参数有些是可选的，当可选参数不填写的时候 会导致实参给形参赋值的时候乱序
    //                 把所有的参数当对象中的属性传递
    //                     {
    //                         url:'接口', 必填
    //                         type:'get|post', 选填，默认值为get
    //                         async:true|false, 选填，默认值为true
    //                         data:'name=aa&age=18' | {name:'aa',age:18} || 没有  ，选填，，默认值:''
    //                         success:function(){}, 必填
    //                         error:fucntion(){}    选填 默认值：function(){}
    //                     }
function ajax(option) {
    // 【1】判断option的数据类型，如果不是对象，手动抛出错误
    if (Object.prototype.toString.call(option) != "[object Object]") {
        throw Error("ajax函数的参数必须是一个对象");
    }

    // 【2】判断必填的属性是否存在 url success
    if (!(option.url && option.success)) {
        throw Error("url 和success 属性是必填的");
    }

    // 【3】success属性的属性值必须是一个函数
    if (Object.prototype.toString.call(option.success) != "[object Function]") {
        throw Error("success属性的属性值必须是一个函数");
    }

    // 【4】async的值是否是布尔值
    if (
        option.async &&
        Object.prototype.toString.call(option.async) != "[object Boolean]"
    ) {
        throw Error("async 的取值必须是布尔值");
    }

    // 【5】给选填的属性添加默认值
    let param = {
        url: option.url,
        type: option.type || "get",
        async: option.async == false ? option.async : true,
        data: option.data || "",
        success: option.success,
        error: option.error || function () {},
    };

    // 【6】判断type属性属性值是否为get 和post
    if (!(param.type == "get" || param.type == "post")) {
        throw Error("type属性的取值暂时只支持get 和post");
    }

    // 【7】data 属性的判断
    // data 数据类型只能为字符串 或者 对象
    if (
        !(
            Object.prototype.toString.call(param.data) == "[object String]" ||
            Object.prototype.toString.call(param.data) == "[object Object]"
        )
    ) {
        throw Error("data属性的值 只支持字符串或者 对象");
    }

    // 【8】如果data属性的值为对象 需要把对象转换为字符串
    if (Object.prototype.toString.call(param.data) == "[object Object]") {
        let str = "";
        for (let key in param.data) {
            str += key + "=" + param.data[key] + "&";
        }
        param.data = str.substr(0, str.length - 1);
    }

    // 发送ajax请求
    let xhr = new XMLHttpRequest();
    if (param.type == "get") {
        xhr.open(param.type, param.url + "?" + param.data, param.async);
        xhr.send();
    } else {
        xhr.open(param.type, param.url, param.async);
        xhr.setRequestHeader(
            "Content-type",
            "application/x-www-form-urlencoded"
        );
        xhr.send(param.data);
    }

    if (param.async == false) {
        if (/^[23]\d{2}$/.test(xhr.status)) {
            param.success(xhr.responseText);
        } else {
            param.error(xhr.responseText);
        }
    }

    // 事件驱动程序
    // onload事件 当ajax请求状态码为4 的时候 执行
    xhr.onload = function () {
        if (/^[23]\d{2}$/.test(xhr.status)) {
            param.success(xhr.responseText);
        } else {
            param.error(xhr.responseText);
        }
    };
}
// 16. 封装一个有promise的ajax请求
// 只是给pAjax返回一个promise对象
function pAjax(option) {
    return new Promise((resolve, reject) => {   
        ajax({
            url: option.url,
            type: option.type,
            data: option.data,
            async: option.async,
            success(res) {
                resolve(res);
            },
            error: function (err) {
                reject(err);
            },
        });
    });
}

// 17.设置一个cookie的函数
function setCookie(key, value, expires) {
    if (!key || !value) {
        throw Error("key 和 value是必填");
    }

    // 判断是否有过期时间
    if (!expires) {
        document.cookie = `${key}=${value};path=/;`;
        return;
    }

    let date = new Date();
    let time = date.getTime() - 8 * 60 * 60 * 1000 + expires * 60 * 1000;
    date.setTime(time); // 根据时间戳得到这个时间戳的时间对象
    document.cookie = `${key}=${value};path=/;expires=${date}`;
}

// 18.获取cookie的内容
function getCookie(key) {
    let cookie = document.cookie;
    let arr = cookie.split("; ");
    let obj = {};
    arr.forEach((item) => {
        let res = item.split("=");
        obj[res[0]] = res[1];
    });

    if (!key) return obj;

    return obj[key];
}
